/*
 * Copyright 2013 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package co.sanduche.util;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.util.Log;
import co.sanduche.app.SanducheApp;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;

/**
 * Main UI for the demo app.
 */
public class GCMRegistrationManager {

	public static final String EXTRA_MESSAGE = "message";
	public static final String PROPERTY_REG_ID = "registration_id";
	private static final String PROPERTY_APP_VERSION = "appVersion";
	private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;

	/**
	 * Substitute you own sender ID here. This is the project number you got
	 * from the API Console, as described in "Getting Started."
	 */
	private static final String SENDER_ID = "339820805477";

	/**
	 * Tag used on log messages.
	 */
	private static final String TAG = "Sanduche GCM Register";

	// static AtomicInteger msgId = new AtomicInteger();

	private static String regid;

	public static void register(Activity activity, EPCallback<String> callback) {
		Context context = activity.getApplicationContext();

		// Check device for Play Services APK. If check succeeds, proceed with
		// GCM registration.
		if (checkPlayServices(activity)) {
			regid = getRegistrationId(context);

			if (regid.isEmpty()) {
				registerInBackground(context, callback);
			}
		} else {
			Log.i(TAG, "No valid Google Play Services APK found.");
		}
	}

	/**
	 * Check the device to make sure it has the Google Play Services APK. If it
	 * doesn't, display a dialog that allows users to download the APK from the
	 * Google Play Store or enable it in the device's system settings.
	 * 
	 * @param activity
	 */
	private static boolean checkPlayServices(Activity activity) {
		int resultCode = GooglePlayServicesUtil
				.isGooglePlayServicesAvailable(activity.getApplicationContext());
		if (resultCode != ConnectionResult.SUCCESS) {
			if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
				GooglePlayServicesUtil.getErrorDialog(resultCode, activity,
						PLAY_SERVICES_RESOLUTION_REQUEST).show();
			} else {
				Log.i(TAG, "This device is not supported.");
			}
			return false;
		}
		return true;
	}

	/**
	 * Stores the registration ID and the app versionCode in the application's
	 * {@code SharedPreferences}.
	 * 
	 * @param context
	 *            application's context.
	 * @param regId
	 *            registration ID
	 */
	private static void storeRegistrationId(Context context, String regId) {
		final SharedPreferences prefs = SanducheApp.getInstance()
				.getGlobalSharedPreferences();
		int appVersion = getAppVersion(context);
		Log.i(TAG, "Saving regId on app version " + appVersion);
		SharedPreferences.Editor editor = prefs.edit();
		editor.putString(PROPERTY_REG_ID, regId);
		editor.putInt(PROPERTY_APP_VERSION, appVersion);
		editor.commit();
	}

	/**
	 * Gets the current registration ID for application on GCM service, if there
	 * is one.
	 * <p>
	 * If result is empty, the app needs to register.
	 * 
	 * @return registration ID, or empty string if there is no existing
	 *         registration ID.
	 */
	public static String getRegistrationId(Context context) {
		final SharedPreferences prefs = SanducheApp.getInstance()
				.getGlobalSharedPreferences();
		String registrationId = prefs.getString(PROPERTY_REG_ID, "");
		if (registrationId.isEmpty()) {
			Log.i(TAG, "Registration not found.");
			return "";
		}
		// Check if app was updated; if so, it must clear the registration ID
		// since the existing regID is not guaranteed to work with the new
		// app version.
		int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION,
				Integer.MIN_VALUE);
		int currentVersion = getAppVersion(context);
		if (registeredVersion != currentVersion) {
			Log.i(TAG, "App version changed.");
			return "";
		}
		return registrationId;
	}

	/**
	 * Registers the application with GCM servers asynchronously.
	 * <p>
	 * Stores the registration ID and the app versionCode in the application's
	 * shared preferences.
	 */
	private static void registerInBackground(final Context context,
			final EPCallback<String> callback) {
		new AsyncTask<Void, Void, String>() {
			@Override
			protected String doInBackground(Void... params) {
				String msg = "";
				try {
					GoogleCloudMessaging gcm = GoogleCloudMessaging
							.getInstance(context);
					Log.i(TAG, "A punto de registrar");
					regid = gcm.register(SENDER_ID);
					Log.i(TAG, "Device registered, registration ID=" + regid);

					// You should send the registration ID to your server over
					// HTTP, so it
					// can use GCM/HTTP or CCS to send messages to your app.
					callback.onSuccess(regid);

					// For this demo: we don't need to send it because the
					// device will send
					// upstream messages to a server that echo back the message
					// using the
					// 'from' address in the message.

					// Persist the regID - no need to register again.
					storeRegistrationId(context, regid);
				} catch (Exception ex) {
					msg = "Error :" + ex.getMessage();
					Log.e(TAG, msg);
					callback.onFailure(ex);
				}
				return msg;
			}

			@Override
			protected void onPostExecute(String msg) {
				Log.i(GCMRegistrationManager.class.getSimpleName(),
						"Register ID: " + regid);
			}
		}.execute(null, null, null);
	}

	// Send an upstream message.
	public static void sendMessage(final Context context) {

		// new AsyncTask<Void, Void, String>() {
		// @Override
		// protected String doInBackground(Void... params) {
		// String msg = "";
		// try {
		// Bundle data = new Bundle();
		// data.putString("my_message", "Hello World");
		// data.putString("my_action",
		// "com.google.android.gcm.demo.app.ECHO_NOW");
		// String id = Integer.toString(msgId.incrementAndGet());
		// GoogleCloudMessaging gcm = GoogleCloudMessaging
		// .getInstance(context);
		// gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data);
		// msg = "Sent message";
		// } catch (IOException ex) {
		// msg = "Error :" + ex.getMessage();
		// }
		// return msg;
		// }
		//
		// @Override
		// protected void onPostExecute(String msg) {
		// Log.i(GCMRegistrationManager.class.getSimpleName(), msg);
		// }
		// }.execute(null, null, null);
	}

	/**
	 * @return Application's version code from the {@code PackageManager}.
	 */
	private static int getAppVersion(Context context) {
		try {
			PackageInfo packageInfo = context.getPackageManager()
					.getPackageInfo(context.getPackageName(), 0);
			return packageInfo.versionCode;
		} catch (NameNotFoundException e) {
			// should never happen
			throw new RuntimeException("Could not get package name: " + e);
		}
	}
}
